package com.xuetang9.fujian.mychat.net;

import com.xuetang9.fujian.mychat.biz.ServerBiz;
import com.xuetang9.fujian.mychat.entity.BizType;
import com.xuetang9.fujian.mychat.entity.User;
import com.xuetang9.fujian.mychat.util.SysDTO;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;


/**
 * @author: fujian
 * @description: 用来处理与传入的客户端的交互
 * @date: 2021/5/10 15:36
 * @version: V1.0
 * @package: com.xuetang9.fujian.mychat.net
 **/
public class SocketHandler implements Runnable{
    public static final int RUNNING = 1;
    public static final int CLOSE = 2;

    private Socket socket;
    private String clientName;
    private ServerBiz serverBiz;
    private User currentUser;
    private ObjectInputStream inputStream;
    private ObjectOutputStream outputStream;
    private int status;  //设置当前客户端的在线或者离线

    public SocketHandler(Socket socket) {
        this.socket = socket;
        setStatus(RUNNING);
        this.serverBiz = new ServerBiz();
        // 拿到与客户端进行交互时的输入输出流
        try {
            inputStream = new ObjectInputStream(socket.getInputStream());
            outputStream = new ObjectOutputStream(socket.getOutputStream());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
        Object data = null;
        while (true) {
            try {
                if ((data=inputStream.readObject())!=null){
                    // 处理流程为：
                    // 1、判断客户端发来的对象类型是否为SysDTO
                    // 2、根据DTO对象的业务类型调用相应的业务方法
                    // 3、将业务方法的返回结果发送给客户端
                    if (!(data instanceof SysDTO)){
                        System.out.println("无法处理客户端请求的业务：" + data);
                        continue;
                    }
                    SysDTO dto = (SysDTO) data;
                    if (null == clientName){
                        clientName = dto.getNickName();
                    }
                    if (dto.getBizType() == BizType.退出){
                        System.out.println(dto.getNickName() + "请求退出下线");
                        closeHandler(dto);
                        break;
                    }
                    //根据客户端请求的业务类型调用相应的业务
                    dto = serverBiz.dealWithDTO(dto);
                    if (dto.getBizType() == BizType.登录成功){
                        this.currentUser = dto.getUser();
                    }
                    outputStream.writeObject(dto);
                    outputStream.flush();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    }
    /*
     * @Description: 为了实现私聊功能，在处理器中单独定义一个发送一个消息
     * @param: dto
     * @return void
     * @author: fujian
     * @date 2021/5/11 21:21
    */
    public void sendDTO(SysDTO dto) throws IOException {
        outputStream.writeObject(dto);
        outputStream.flush();
    }

    private void closeHandler(SysDTO dto){
        dto.setBizType(BizType.退出成功);
        try {
            sendDTO(dto);
            Thread.sleep(10000);
            inputStream.close();
            outputStream.close();
            socket.close();
            setStatus(CLOSE);
            System.out.println(dto.getNickName() + "下线了");
        } catch (InterruptedException | IOException e) {
            e.printStackTrace();
        }
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getClientName() {
        return clientName;
    }

    public User getCurrentUser() {
        return currentUser;
    }
}
